package com.newfiber.workflow.support;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newfiber.common.core.exception.ServiceException;
import com.newfiber.workflow.enums.EConstantValue;
import com.newfiber.workflow.utils.ApplicationContextProvider;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.stereotype.Component;

/**
 * @author : X.K
 * @since : 2023/3/22 下午4:31
 */
@Component
@SuppressWarnings("unchecked")
public class WorkflowDefinitionAccessor {

	private final Set<Class<? extends Enum<?>>> workflowDefinitionSet = new HashSet<>();

	public String getWorkflowName(String workflowKey){
		Class<? extends Enum<?>> workflowDefinition = getWorkflowDefinition(workflowKey);
		return EnumUtil.getFieldValues(workflowDefinition, WorkflowDefinitionConstant.WorkflowName.value).get(0).toString();
	}

	public String getTablePrimary(String workflowKey){
		Class<? extends Enum<?>> workflowDefinition = getWorkflowDefinition(workflowKey);
		return EnumUtil.getFieldValues(workflowDefinition, WorkflowDefinitionConstant.TablePrimary.value).get(0).toString();
	}

	public String getWorkflowInstanceFieldName(String workflowKey){
		return EConstantValue.WorkflowInstanceFieldName.getValue();
	}

	public ServiceImpl<?, ?> getBusinessService(String workflowKey){
		Class<? extends Enum<?>> workflowDefinition = getWorkflowDefinition(workflowKey);
		if(null == workflowDefinition){
			throw new ServiceException(String.format("工作流定义不存在:%s", workflowKey));
		}

		Class<? extends ServiceImpl<?, ?>> service = (Class<? extends ServiceImpl<?, ?>>) EnumUtil.getFieldValues(workflowDefinition, WorkflowDefinitionConstant.BusinessService.value).get(0);
		return ApplicationContextProvider.getBean(service);
	}

	private Class<? extends Enum<?>> getWorkflowDefinition(String workflowKey){
		for(Class<? extends Enum<?>> workflowDefinition : workflowDefinitionSet){
			List<Object> workflowKeyList = EnumUtil.getFieldValues(workflowDefinition, WorkflowDefinitionConstant.WorkflowKey.value);
			if(workflowKeyList.contains(workflowKey)){
				return workflowDefinition;
			}
		}
		throw new ServiceException(String.format("工作流定义不存在:%s", workflowKey));
	}

	@PostConstruct
	public void registerWorkflowDefinition(){
		Set<Class<?>> classes = ClassUtil.scanPackage(WorkflowDefinitionConstant.GLOBAL_PACKAGE.value);
		for(Class<?> clazz : classes){
			if(clazz.isEnum() && ReflectUtil.hasField(clazz, WorkflowDefinitionConstant.WorkflowKey.value)){
				workflowDefinitionSet.add((Class<? extends Enum<?>>)clazz);
			}
		}
	}

	@Getter
	@AllArgsConstructor
	enum WorkflowDefinitionConstant{
		/**
		 *
		 */
		GLOBAL_PACKAGE("全局包名", "com.newfiber"),
		WorkflowKey("枚举字段", "workflowKey"),
		WorkflowName("枚举字段", "workflowName"),
		TablePrimary("枚举字段", "tablePrimary"),
		BusinessService("枚举字段", "businessService"),

		;

		private final String name;
		private final String value;
	}
}
